﻿using System.Data;
using System.Data.SqlClient;
using System.Reflection;

namespace AndyT4
{
    internal class Program
    {

        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            Dictionary<string, List<Column>> dic=GetColumns();

            foreach (var tableName in dic.Keys) { 
            
                List<Column> col = dic[tableName];

                foreach (var column in col) {

                    Console.WriteLine(column.Name);
                    Console.WriteLine(column.Description);
                }
            
            }

        }

        public string ConvertType(string type) {
            if (type.Contains("char")) {
                return "string";
            }

            if (type.Equals("bigint"))
            {
                return "long";
            }

            if (type.Equals("datetime"))
            {
                return "DataTime";
            }

            return type;
        }



        /// <summary>
        /// DataTable转成List
        /// </summary>
        public static List<T> ToDataList<T>(DataTable dt)
        {
            var list = new List<T>();
            var plist =new List<PropertyInfo>(typeof(T).GetProperties());
            foreach (DataRow item in dt.Rows)
            {
                T s = Activator.CreateInstance<T>();
                //遍历dataTable中的列集合
                for (int i = 0; i < dt.Columns.Count; i++)
                {
                    //获取属性和DataTable的列名称相同的属性(PropertyInfo)
                    PropertyInfo info = plist.Find(p => p.Name.ToLower() == dt.Columns[i].ColumnName.ToLower());
                    //判断是否存在
                    if (info != null)
                    {
                        try
                        {
                            //判断是否为空
                            if (!Convert.IsDBNull(item[i]))
                            {
                                object v = null;
                                //判断属性是否包含可空
                                if (info.PropertyType.ToString().Contains("System.Nullable"))
                                {
                                    //类型转换
                                    v = Convert.ChangeType(item[i], Nullable.GetUnderlyingType(info.PropertyType));
                                }
                                else
                                {
                                    //类型转换
                                    v = Convert.ChangeType(item[i], info.PropertyType);
                                }
                                //赋值
                                info.SetValue(s, v, null);
                            }
                        }
                        catch (Exception ex)
                        {
                            throw new Exception("字段[" + info.Name + "]转换出错," + ex.Message);
                        }
                    }
                }
                list.Add(s);
            }
            return list;
        }

        public static Dictionary<string, List<Column>> GetColumns()
        {
            SqlConnection conn = new SqlConnection("server=.;uid=sa;pwd=123456;database=mytest;TrustServerCertificate=true");
            conn.Open();
            Dictionary<string, List<Column>> keyValuePairs = new Dictionary<string, List<Column>>();

            DataTable dbat = conn.GetSchema("Tables");
            foreach (DataRow row in dbat.Rows)
            {
                string tableName = row["TABLE_NAME"].ToString();


                string sql = $"SELECT '{tableName}' as tablename,a.name [name], b.name type, a.prec length, isnull(c.value, ' ') [description],a.isnullable  isnullable " +
                    $"FROM syscolumns a " +
                    $"LEFT OUTER JOIN systypes b ON a.xusertype = b.xusertype " +
                    $"LEFT OUTER JOIN sys.extended_properties c ON a.id = c.major_id AND a.colid = c.minor_id WHERE a.id = object_id('{tableName}')";

                DataTable dt = new DataTable();
                SqlDataAdapter da = new SqlDataAdapter(sql, conn);
                dt.Clear();
                da.Fill(dt);

                List<Column> columns = ToDataList<Column>(dt);

                keyValuePairs.Add(tableName, columns);
            }

            conn.Close();

            return keyValuePairs;
        }

        public string ToPascal(string str)
        {
            string[] split = str.Split(new char[] { '/', ' ', '_', '.' });
            string newStr = string.Empty;
            foreach (var item in split)
            {
                char[] chars = item.ToCharArray();
                chars[0] = char.ToUpper(chars[0]);
                for (int i = 1; i < chars.Length; i++)
                {
                    chars[i] = char.ToLower(chars[i]);
                }
                newStr += new string(chars);
            }
            return newStr;
        }

       
        public class Column
        {
            public string TableName { get; set; }=string.Empty;
            public string Name { get; set; }= string.Empty; 
            public string Type { get; set; } = string.Empty;
            public string Description { get; set; } = string.Empty;

            public bool IsNullable { get; set; }

        }

        /// <summary>
        /// 数据列
        /// </summary>
        //public class Column
        //{
        //    DataColumn columnBase;

        //    public Column(DataColumn _columnBase)
        //    {
        //        columnBase = _columnBase;
        //        columnBase..Capture
        //    }

        //    public string ColumnName { get { return columnBase.ColumnName; } }

        //    public string DataType
        //    {
        //        get
        //        {
        //            string result = string.Empty;
        //            if (columnBase.DataType.Name == "String")
        //                result = "string";
        //            else if (columnBase.DataType.Name == "Int32")
        //                result = "int";
        //            else
        //                result = columnBase.DataType.Name;
        //            return result;
        //        }
        //    }
        //}
    }
}
